package com.foreveross.chameleon.manager;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import org.apache.http.util.EncodingUtils;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.darin.cl.http.CLHttpUtil;
import com.darin.cl.task.CLTask;
import com.darin.cl.task.CLTaskManager;
import com.darin.cl.util.CLFileUtil;
import com.foreveross.BroadcastConstant;
import com.foreveross.URL;
import com.foreveross.chameleon.CheckInUtil;
import com.foreveross.chameleon.CubeSettingActivity;
import com.foreveross.chameleon.manager.task.InstallModuleTask;
import com.foreveross.chameleon.manager.task.UpgradeModuleTask;
import com.foreveross.chameleon.parser.CubeContentParser;
import com.foreveross.chameleon.parser.UserPrivilegeParser;
import com.foreveross.chameleon.view.CubeAndroid;
import com.foreveross.chameleonsdk.ChameleonSDK;
import com.foreveross.pojo.CubeContent;
import com.foreveross.pojo.CubeModule;
import com.foreveross.pojo.CubeModuleDownloadInfo;
import com.foreveross.pojo.Privilege;
import com.foreveross.pojo.UserPrivilege;
import com.foreveross.util.Preferences;
import com.foreveross.util.PropertiesUtil;
import com.foreveross.zillasdk.ZillaListener;
import com.foreveross.zillasdk.ZillaManager;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class CubeContentManager {

	private static CubeContentManager contentManager = null;

	private UserPrivilege userPrivilege;
	private CLTaskManager mClTaskManager;

	private HashMap<String, CLTask> mDownIngTaskMap;

	private HashMap<String, CubeModule> mWorkIngLinkedMap;
	private HashMap<String, CubeModule> mWaitIngLinkedMap;
	private PropertiesUtil mPropertiesUtil;

	private static final int MCOREPOOLSIZE = 3;
	private static final int MMAXIMUMPOOLSIZE = 3;

	private CubeContentStatus mCubeContentStatus;

	private CubeContent mCubeContent;

	private CubeContentManager() {
		initTaskMananger();
		mCubeContentStatus = new CubeContentStatus();
		mCubeContent = new CubeContent();
	}

	public static CubeContentManager getInstance() {
		if (contentManager == null) {
			contentManager = new CubeContentManager();

		}
		return contentManager;
	}

	/**
	 * 初始化线程池
	 */
	private void initTaskMananger() {
		if (mClTaskManager == null) {
			mClTaskManager = new CLTaskManager(128, MCOREPOOLSIZE,
					MMAXIMUMPOOLSIZE);
			mDownIngTaskMap = new HashMap<String, CLTask>();
			mWorkIngLinkedMap = new HashMap<String, CubeModule>();
			mWaitIngLinkedMap = new HashMap<String, CubeModule>();
		}
		mPropertiesUtil = ChameleonSDK.getCApplication().getCubePropertie();
	}

	public UserPrivilege getUserPrivilege() {
		return userPrivilege;
	}

	public void setUserPrivilege(UserPrivilege userPrivilege) {
		this.userPrivilege = userPrivilege;
	}

	/**
	 * 与服务器同步应用状态，获取模块更新
	 */
	public void syncContent(final ApplicationSyncListener listener,
			final CubeContent app, final Context context, boolean dialogNeed,
			final String dialogContent) {

		ZillaListener callback = new ZillaListener() {

			@Override
			public void requestStart() {
				listener.syncStart();
			}

			@Override
			public void requestSuccess(String result) {
				if (result == null) {
					listener.syncFail();
					return;
				}

				try {
					JSONObject jb = new JSONObject(result);

					if (jb.has("result")
							&& jb.getString("result").equals("error")) {
						listener.syncFail();
						return;
					}
				} catch (JSONException e) {
					e.printStackTrace();
				}

				CubeContentParser contentParser = new CubeContentParser();
				CubeContent remote_app = contentParser.parser(result);

				if (remote_app.getModules() == null) {
					listener.syncFail();
					return;
				}
				CubeContent comparedCubeApp = compareAndSetApp(context, app,
						remote_app);
				mCubeContentStatus.init(comparedCubeApp);
				save(context, app);
				listener.syncFinish(null);
			}

			@Override
			public void requestFailed(Exception error) {
				Log.v("sync", "同步失败");
				listener.syncFail();
			}

		};
		ZillaManager.getInstance().syncModule(context, callback, dialogNeed,
				dialogContent);
	}

	public void syncContentPrivilege(boolean dialogNeed, final Context context,
			final String username, final ApplicationSyncListener callback,
			final String dialogContent) {
		ZillaListener delegate = new ZillaListener() {

			@Override
			public void requestSuccess(String result) {
				Log.d("syncPrivilege", result);

				try {
					Preferences.saveUser(username);
					UserPrivilegeParser parser = new UserPrivilegeParser();
					UserPrivilege userPrivilege = parser.parser(result);
					CubeContentManager.getInstance().setUserPrivilege(
							userPrivilege);
					CheckInUtil.pushSecurity(context, userPrivilege.getRole());

					ArrayList<String> privilegeList = userPrivilege
							.getPrivilegeList();
					Set<CubeModule> modules = mCubeContent.getModules();
					for (CubeModule cubeModule : modules) {
						if (privilegeList.contains(cubeModule.getIdentifier())) {
							List<Privilege> prList = new ArrayList<Privilege>();
							cubeModule.setPrivileges(prList);
						} else {
							cubeModule.setPrivileges(null);
						}
					}
					mCubeContentStatus.init(mCubeContent);
					save(context, mCubeContent);
					callback.syncFinish(result);
				} catch (Exception e) {
					e.printStackTrace();
				}

			}

			@Override
			public void requestStart() {
				callback.syncStart();

			}

			@Override
			public void requestFailed(Exception error) {
				callback.syncFail();

			}
		};

		ZillaManager.getInstance().syncPrivilege(context, delegate, username,
				dialogNeed, dialogContent);
	}

	public synchronized CubeContent compareAndSetApp(Context context,
			CubeContent oldOne, CubeContent newOne) {
		if (oldOne == null) {
			return newOne;
		}

		Set<CubeModule> oldSet = new HashSet<CubeModule>(oldOne.getModules());
		Set<CubeModule> newSet = new HashSet<CubeModule>(newOne.getModules());
		// Map<String, CubeModule> oldHash = bulidMap(oldSet);
		Map<String, CubeModule> newHash = bulidMap(newSet);

		Map<String, CubeModule> unstallMap = new HashMap<String, CubeModule>();
		Map<String, CubeModule> installedMap = new HashMap<String, CubeModule>();
		Map<String, CubeModule> updatableMap = new HashMap<String, CubeModule>();

		oldOne.getOldUpdateModules().clear();
		oldOne.getNewUpdateModules().clear();
		for (CubeModule cubeModule : oldSet) {
			for (CubeModule module : newSet) {
				// 同步本地已存在模块和服务器模块信息
				if (cubeModule.getIdentifier().equals(module.getIdentifier())) {
					// cubeModule.setVersion(module.getVersion());
					cubeModule.setCategory(module.getCategory());
					cubeModule.setAutoDownload(module.isAutoDownload());
					cubeModule.setAutoShow(module.isAutoShow());
					cubeModule.setTimeUnit(module.getTimeUnit());
					cubeModule.setName(module.getName());
					cubeModule.setReleaseNote(module.getReleaseNote());
					cubeModule
							.setShowIntervalTime(module.getShowIntervalTime());
					cubeModule.setPrivileges(module.getPrivileges());
					cubeModule.setHidden(module.isHidden());
					cubeModule.setDownloadUrl(URL.getDownloadUrl(context,
							module.getBundle()));
					cubeModule.setSortingWeight(module.getSortingWeight());
					cubeModule.setInstallIcon(URL.getDownloadUrl(context,
							module.getIcon()));

					if (cubeModule.getLocal() == null) {
						if (cubeModule.getModuleType() != CubeModule.INSTALLED) {

							cubeModule.setIcon(URL.getDownloadUrl(context,
									module.getIcon()));
						} else {
							if (!isExist(context, module, "icon.img")) {
								if (isExist(context, module, "icon.png")) {
									cubeModule.setIcon(URL.getSdPath(context,
											module.getIdentifier()
													+ "/icon.png"));

								} else {
									cubeModule.setIcon(URL.getDownloadUrl(
											context, module.getIcon()));
								}
							}
							// 设置默认图标
						}
					} else {
						// 判断本地模块是否存在
						String icon = mPropertiesUtil.getString("icon_"
								+ cubeModule.getIdentifier(), "");
						cubeModule.setIcon(icon);
					}
					break;
				}
			}
			switch (cubeModule.getModuleType()) {
			case CubeModule.DELETING: {
				installedMap.put(cubeModule.getIdentifier(), cubeModule);
				break;
			}
			case CubeModule.INSTALLED: {
				installedMap.put(cubeModule.getIdentifier(), cubeModule);
				break;
			}
			case CubeModule.UNINSTALL: {
				unstallMap.put(cubeModule.getIdentifier(), cubeModule);
				break;
			}
			case CubeModule.INSTALLING: {
				unstallMap.put(cubeModule.getIdentifier(), cubeModule);
				break;
			}
			case CubeModule.UPGRADABLE: {
				updatableMap.put(cubeModule.getIdentifier(), cubeModule);
				break;
			}
			case CubeModule.UPGRADING: {
				updatableMap.put(cubeModule.getIdentifier(), cubeModule);
				break;
			}
			}
		}

		for (CubeModule cubeNew : newSet) {
			// if (cubeNew.getIdentifier().contains("chat")) {
			// System.out.println("nm");
			// }
			String identify = cubeNew.getIdentifier();
			int build = cubeNew.getBuild();
			if (unstallMap.get(identify) == null
					&& installedMap.get(identify) == null) {

				cubeNew.setDownloadUrl(URL.getDownloadUrl(context,
						cubeNew.getBundle()));
				if (cubeNew.getLocal() != null) {
					// 判断本地模块是否存在
					String icon = mPropertiesUtil.getString(
							"icon_" + cubeNew.getIdentifier(), "");
					cubeNew.setIcon(icon);
				} else {
					cubeNew.setIcon(URL.getDownloadUrl(context,
							cubeNew.getIcon()));

				}
				unstallMap.put(cubeNew.getIdentifier(), cubeNew);

			} else if (unstallMap.get(identify) != null
					&& build != unstallMap.get(identify).getBuild()) {
				cubeNew.setDownloadUrl(URL.getDownloadUrl(context,
						cubeNew.getBundle()));
				cubeNew.setIcon(URL.getDownloadUrl(context, cubeNew.getIcon()));
				unstallMap.remove(identify);
				unstallMap.put(cubeNew.getIdentifier(), cubeNew);

			} else if (installedMap.get(identify) != null) {
				CubeModule x = installedMap.get(identify);

				if (build <= x.getBuild()) {
					x.setUpdatable(false);
					updatableMap.remove(identify);

				} else if (build > x.getBuild()) {
					x.setUpdatable(true);
					cubeNew.setModuleType(CubeModule.UPGRADABLE);
					cubeNew.setUpdatable(true);
					cubeNew.setDownloadUrl(URL.getDownloadUrl(context,
							cubeNew.getBundle()));
					cubeNew.setIcon(URL.getDownloadUrl(context,
							cubeNew.getIcon()));
					updatableMap.put(cubeNew.getIdentifier(), cubeNew);
					oldOne.getOldUpdateModules().put(x.getIdentifier(), x);
					oldOne.getNewUpdateModules().put(cubeNew.getIdentifier(),
							cubeNew);

				}
			}

		}

		CopyOnWriteArraySet<CubeModule> set = new CopyOnWriteArraySet<CubeModule>(
				oldSet);
		for (CubeModule module : set) {
			if (!newSet.contains(module)
					&& newHash.get(module.getIdentifier()) == null) {
				unstallMap.remove(module.getIdentifier());
				installedMap.remove(module.getIdentifier());
				updatableMap.remove(module.getIdentifier());
			}
		}
		// 1.未安装：有新旧对象，则取新对象
		// 2.已安装: 看是否有更新对象，如果没有再设置为UPGRADABLE,再设置updatable为true
		// 如果有更新对象，则比较两版本的区别，取最新版

		oldOne.getModules().clear();
		oldOne.getModules().addAll(installedMap.values());
		oldOne.getModules().addAll(updatableMap.values());
		oldOne.getModules().addAll(unstallMap.values());
		return oldOne;
	}

	public Map<String, CubeModule> bulidMap(Set<CubeModule> list) {
		Map<String, CubeModule> hash = new HashMap<String, CubeModule>();
		for (CubeModule cubeModule : list) {
			if (cubeModule == null) {
				continue;
			}
			hash.put(cubeModule.getIdentifier(), cubeModule);
		}
		return hash;
	}

	public boolean isExist(Context context, CubeModule cubeModule, String name) {
		String path = URL.getSdPath(context, cubeModule.getIdentifier()) + "/"
				+ name;
		File f = new File(path);
		if (f.exists()) {
			return true;
		} else {
			return false;
		}
	}

	public void save(Context context, CubeContent app) {
		String name = "Cube";
		GsonBuilder builder = new GsonBuilder();
		Gson gson = builder.create();
		String json = gson.toJson(app);
		try {
			CLFileUtil.writeStringToFile(json, Environment
					.getExternalStorageDirectory().getPath()
					+ "/"
					+ URL.APP_PACKAGENAME + "/" + name + ".json");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/***
	 * 加载SD卡里的cube.json,如果为空则加载assets里的cube.json文件
	 */

	public void loadCubeContent(Context context) {

		if (isInstalled(context)) {
			// 运行目录读取
			System.out.println("运行时目录读取");
			String path = Environment.getExternalStorageDirectory().getPath();
			String name = "Cube" + ".json";
			String results = CLFileUtil.readFile(path + "/"
					+ context.getPackageName() + "/" + name);
			CubeContentParser contentParser = new CubeContentParser();
			CubeContent app = contentParser.parser(results);

			// // 同步预置模块
			copyProperties(context, app);

		} else {
			// assets目录读取
			System.out.println("assets目录读取");
			InputStream is = null;
			String results = "";
			try {
				is = context.getResources().getAssets().open("Cube.json");
				int lenght = is.available();
				byte[] buffer = new byte[lenght];
				is.read(buffer);
				results = EncodingUtils.getString(buffer, "ENCODING");

			} catch (Exception e) {
				e.printStackTrace();
			}
			CubeContentParser contentParser = new CubeContentParser();
			CubeContent app = contentParser.parser(results);

			copyProperties(context, app);

			/** 拷贝应用信息至SD卡 */
			try {
				copyJsonToSd(context);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 判断运行时目录是否存在Cube.json 文件。
	 * 
	 * @return
	 */
	public boolean isInstalled(Context context) {
		String path = Environment.getExternalStorageDirectory().getPath();
		Boolean isExist = CLFileUtil.isExistFile(path + "/"
				+ URL.APP_PACKAGENAME + "/" + "Cube.json");
		return isExist;
	}

	/**
	 * 安装应用，将文件复制到运行时目录
	 * 
	 */
	public void copyJsonToSd(Context context) throws IOException {
		// 复制Assets文件夹中的Cube.json 文件到运行时目录。
		String path = Environment.getExternalStorageDirectory().getPath() + "/"
				+ URL.APP_PACKAGENAME;
		File file = new File(path);
		if (!file.exists()) {
			file.mkdirs();
		}
		CLFileUtil.copyAssetsFile(context, "Cube.json", path + "/"
				+ "Cube.json");

	}

	/***
	 * 初始化cubeContent
	 * 
	 * @param a
	 */
	public void copyProperties(Context context, CubeContent a) {
		mCubeContent.setIdentifier(a.getPackageName());
		mCubeContent.setBuild(a.getVersionCode());
		mCubeContent.setIcon(a.getIcon());
		mCubeContent.setModules(a.getModules());
		mCubeContent.setName(a.getName());
		mCubeContent.setReleaseNote(a.getReleaseNote());
		mCubeContent.setVersion(a.getVersionName());
		mCubeContent.setPlatform(a.getPlatform());
		mCubeContent.setAppKey(a.getAppKey());
	}

	public synchronized void downLoadOrUpgradeModule(CubeModule module,
			Context mcontext) {
		if (mWorkIngLinkedMap.containsKey(module.getIdentifier())
				|| mWaitIngLinkedMap.containsKey(module.getIdentifier())) {
			return;
		}
		if (mWorkIngLinkedMap.size() > (MCOREPOOLSIZE - 1)) {
			mWaitIngLinkedMap.put(module.getIdentifier(), module);
		} else {
			mWorkIngLinkedMap.put(module.getIdentifier(), module);
			if (isInstall(module)) {
				upgrade(module, ChameleonSDK.getCApplication().getContext());
			} else {
				install(module, ChameleonSDK.getCApplication().getContext());
			}
		}
	}

	/**
	 * [安装应用]<BR>
	 * [功能详细描述]
	 * 
	 * @param cubeModule
	 *            2013-7-16 上午11:51:48
	 */
	private void install(final CubeModule module, final Context mcontext) {

		CubeModuleDownloadInfo bean = new CubeModuleDownloadInfo();
		bean.setModule(module);
		bean.setDownloadUrl(module.getDownloadUrl());
		bean.setFileDir(Environment.getExternalStorageDirectory() + "/"
				+ URL.APP_PACKAGENAME + "/www/" + module.getIdentifier());
		bean.setFilePath(Environment.getExternalStorageDirectory() + "/"
				+ URL.APP_PACKAGENAME + "/" + module.getIdentifier() + ".zip");
		CLHttpUtil clHttpUtil = new CLHttpUtil(module.getDownloadUrl());
		InstallModuleTask task = new InstallModuleTask(bean, clHttpUtil,
				mcontext) {

			@Override
			protected void onPreExecute() {
				// TODO Auto-generated method stub
				super.onPreExecute();
				mDownIngTaskMap.put(module.getIdentifier(), this);
			}

			@Override
			protected void doOnException(Exception exception) {
				// TODO Auto-generated method stub
				// 下载失败
				super.doOnException(exception);
				Log.i("test", "doOnException");
				// 这个模块下载失败
				Toast.makeText(mcontext, module.getName() + "下载失败，请检查网络",
						Toast.LENGTH_SHORT).show();
				if (module != null) {
					module.setModuleType(CubeModule.UNINSTALL);
					mCubeContentStatus.removeFormMain(module);
					AutoDownloadHelper.getInstance().finishDownload(module,
							false);
					BroadCastManager.sentModuleDownloadCount(mcontext);
					if (AutoDownloadHelper.getInstance().getProgressCount() == 0) {
						BroadCastManager.sentModuleDownloadFinsh(mcontext);
						AutoDownloadHelper.getInstance().clear();
					}
					BroadCastManager.refreshMainPage(mcontext, module);
					BroadCastManager.updateProgress(mcontext, module, 101);
				}
			}

			@Override
			public void doOnSuccess(String result) {
				// TODO Auto-generated method stub
				super.doOnSuccess(result);

			}

			@Override
			protected void onFinish() {
				// TODO Auto-generated method stub
				super.onFinish();
				mWorkIngLinkedMap.remove(module.getIdentifier());
				mDownIngTaskMap.remove(module.getIdentifier());
				startWaitIngList();
			}
		};

		mClTaskManager.execute(task);
	}

	/**
	 * [卸载应用]<BR>
	 * [功能详细描述]
	 * 
	 * @param cubeModule
	 *            2013-7-16 上午11:52:09
	 */
	public void uninstall(final CubeModule cubeModule, final Context mcontext) {
		if (!mCubeContentStatus.getAll_map().get(cubeModule.getCategory())
				.contains(cubeModule)) {
			throw new UnsupportedOperationException("你传入的对象不在管理器中");
		}
		cubeModule.setModuleType(CubeModule.DELETING);
		final Context context = mcontext;

		AsyncTask<String, Integer, Boolean> task = new AsyncTask<String, Integer, Boolean>() {
			private int preProgress = -1;

			@Override
			protected void onPreExecute() {
				super.onPreExecute();
				BroadCastManager.updateProgress(context, cubeModule, -1);
			}

			@Override
			protected Boolean doInBackground(String... params) {
				publishProgress(-1);
				String basePath = Environment.getExternalStorageDirectory()
						.getPath() + "/" + URL.APP_PACKAGENAME;
				StringBuilder folderPath = new StringBuilder();
				StringBuilder zipPath = new StringBuilder();
				folderPath.append(basePath).append("/www/")
						.append(cubeModule.getIdentifier());
				zipPath.append(basePath + "/")
						.append(cubeModule.getIdentifier()).append(".zip");
				CLFileUtil.deleteFolder(folderPath.toString());
				CLFileUtil.deleteFile(zipPath.toString());
				return true;
			}

			int flag = 0;

			@Override
			protected void onProgressUpdate(Integer... progress) {
				super.onProgressUpdate(progress);
				int p = progress[0];
				cubeModule.setProgress(p);
				if (p == 0 || p == 100 || (p - preProgress) >= 5) {
					BroadCastManager.updateProgress(context, cubeModule, p);
					preProgress = p;
				}

				if ((flag + p) == -1) {
					flag++;
					BroadCastManager.updateProgress(context, cubeModule, p);
				}
			}

			protected void onPostExecute(Boolean result) {
				super.onPostExecute(result);
				if (result) {
					cubeModule.setModuleType(CubeModule.UNINSTALL);
					cubeModule.setIcon(cubeModule.getInstallIcon());
					mCubeContentStatus.removeFormInstalled(cubeModule);
					if (!cubeModule.isHidden()) {
						mCubeContentStatus.removeFormMain(cubeModule);
					}
					CubeModule newVersion = mCubeContentStatus
							.getIdentifier_new_version_map().get(
									cubeModule.getIdentifier());
					if (newVersion != null) {
						newVersion.setModuleType(CubeModule.UNINSTALL);
						newVersion.setUpdatable(false);
						mCubeContentStatus.removeFormUpdatable(newVersion);
						mCubeContentStatus.removeFormInstalled(cubeModule);
						mCubeContentStatus.add2Uninstalled(newVersion);
						mCubeContentStatus.getIdentifier_new_version_map()
								.remove(newVersion);
						mCubeContentStatus.getIdentifier_old_version_map()
								.remove(cubeModule);
						mCubeContentStatus.getAllSet().remove(newVersion);
						mCubeContent.getOldUpdateModules().remove(
								cubeModule.getIdentifier());
						mCubeContent.getNewUpdateModules().remove(
								newVersion.getIdentifier());
					} else {
						mCubeContentStatus.add2Uninstalled(cubeModule);
					}

					BroadCastManager.refreshModule(context, "uninstall",
							cubeModule);
					Set<CubeModule> storedSet = mCubeContent.getModules();
					storedSet.remove(cubeModule);
					CubeContentManager.getInstance().save(mcontext,
							mCubeContent);
					BroadCastManager.updateProgress(context, cubeModule, 101);
				} else {
					Toast.makeText(mcontext, "删除失败!", Toast.LENGTH_SHORT)
							.show();
					BroadCastManager.updateProgress(context, cubeModule, 101);
				}

			};

		};
		task.execute();
	}

	/**
	 * [更新应用]<BR>
	 * [功能详细描述]
	 * 
	 * @param cubeModule
	 *            2013-7-16 上午11:52:23
	 */
	private void upgrade(final CubeModule module, final Context mcontext) {

		CubeModuleDownloadInfo bean = new CubeModuleDownloadInfo();
		bean.setModule(module);
		bean.setDownloadUrl(module.getDownloadUrl());
		bean.setFileDir(Environment.getExternalStorageDirectory() + "/"
				+ URL.APP_PACKAGENAME + "/www/" + module.getIdentifier());
		bean.setFilePath(Environment.getExternalStorageDirectory() + "/"
				+ URL.APP_PACKAGENAME + "/" + module.getIdentifier() + ".zip");
		CLHttpUtil clHttpUtil = new CLHttpUtil(module.getDownloadUrl());
		UpgradeModuleTask task = new UpgradeModuleTask(bean, clHttpUtil,
				mcontext) {

			@Override
			protected void onPreExecute() {
				// TODO Auto-generated method stub
				super.onPreExecute();
				mDownIngTaskMap.put(module.getIdentifier(), this);
			}

			@Override
			protected void doOnException(Exception exception) {

				// TODO Auto-generated method stub
				// 下载失败
				super.doOnException(exception);
				// 这个模块下载失败
				CubeModule oldModule = mCubeContentStatus
						.getIdentifier_old_version_map().get(
								module.getIdentifier());
				if (oldModule == null) {
					return;
				}
				module.setModuleType(CubeModule.UPGRADABLE);
				module.setUpdatable(true);
				oldModule.setModuleType(CubeModule.INSTALLED);
				oldModule.setUpdatable(true);
				if (!module.isHidden()) {
					mCubeContentStatus.removeFormMain(module);
					mCubeContentStatus.add2Main(oldModule);
					if (isExist(mcontext, module, "icon.img")) {
						oldModule.setIcon(URL.getSdPath(mcontext,
								module.getIdentifier() + "/icon.img"));
					} else if (isExist(mcontext, module, "icon.png")) {
						oldModule.setIcon(URL.getSdPath(mcontext,
								module.getIdentifier() + "/icon.png"));
					}
				}
				BroadCastManager.sentModuleDownloadCount(mcontext);
				AutoDownloadHelper.getInstance().finishDownload(module, false);
				if (AutoDownloadHelper.getInstance().getProgressCount() == 0) {
					BroadCastManager.sentModuleDownloadFinsh(mcontext);
				}
				BroadCastManager.refreshMainPage(mcontext, module);
				Toast.makeText(mcontext, "网络状态不稳定!", Toast.LENGTH_SHORT).show();
				BroadCastManager.updateProgress(mcontext, module, 101);
			}

			@Override
			public void doOnSuccess(String result) {
				// TODO Auto-generated method stub
				super.doOnSuccess(result);
			}

			@Override
			protected void onFinish() {
				// TODO Auto-generated method stub
				super.onFinish();
				// TODO Auto-generated method stub
				super.onFinish();
				mWorkIngLinkedMap.remove(module.getIdentifier());
				mDownIngTaskMap.remove(module.getIdentifier());
				startWaitIngList();

			}
		};

		mClTaskManager.execute(task);
	}

	public List<CubeModule> checkUpgrade() {
		List<CubeModule> isUpgrade = new ArrayList<CubeModule>();
		if (mCubeContentStatus.getUpdatable_map().size() != 0) {
			for (List<CubeModule> list : mCubeContentStatus.getUpdatable_map()
					.values()) {
				isUpgrade.addAll(list);
			}
		}
		return isUpgrade;

	}

	public ArrayList<CubeModule> checkDepends(String identifier) {
		String path = Environment.getExternalStorageDirectory().getPath() + "/"
				+ URL.APP_PACKAGENAME + "/www/";
		ArrayList<CubeModule> identifierList = new ArrayList<CubeModule>();
		String result = readDependsFile(identifier, path);
		try {
			// 有json文件
			if (null != result) {
				JSONObject jb = new JSONObject(result);
				if (!jb.isNull("dependencies")) {
					JSONObject dependencies = jb.getJSONObject("dependencies");
					if (dependencies.length() != 0) {
						Iterator<?> i = dependencies.keys();
						while (i.hasNext()) {
							String id = (String) i.next();
							// 检查是否安装该模块
							int build = dependencies.getInt(id);
							int size = mCubeContentStatus.getModuleCount(id);
							if (size == 0)
								// 不存在该模块，自动跳过
								continue;
							if (size == 1) {
								CubeModule module = mCubeContentStatus
										.getModuleByIdentify(id);
								int type = module.getModuleType();
								if (type != CubeModule.INSTALLED) {
									Log.v("Depends", "缺少依赖模块");
									identifierList.add(module);
									Log.v("Depends", "该模块可能未安装/在下载中/在更新中/在删除中");
								} else {
									Log.v("Depends", "不缺少依赖模块");
								}
							} else {
								// 模块有更新，取旧版本下载依赖
								CubeModule newModule = mCubeContentStatus
										.getIdentifier_new_version_map()
										.get(id);
								CubeModule module = mCubeContentStatus
										.getIdentifier_old_version_map()
										.get(id);
								if (module == null || newModule == null) {
									continue;
								}
								int type = module.getModuleType();
								if (type == CubeModule.INSTALLED) {
									if (build > module.getBuild()) {
										Log.v("Depends", "存在版本小于依赖版本");
										identifierList.add(newModule);
									} else {
										Log.v("Depends", "不缺少依赖模块");
									}
								} else {
									Log.v("Depends", "缺少依赖模块");
									identifierList.add(module);
									Log.v("Depends", "该模块可能未安装/在下载中/在更新中/在删除中");
								}
							}

						}
					}
				}
			} else {
				Log.v("Depends", "没有CubeModulejson文件");
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return identifierList;
	}

	public static String readDependsFile(String identifier, String path) {

		String result = null;
		if (Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			File s = new File(path + identifier + "/CubeModule.json");
			try {
				FileInputStream in = new FileInputStream(s);
				// 获取文件的字节数
				int lenght = in.available();
				// 创建byte数组
				byte[] buffer = new byte[lenght];
				// 将文件中的数据读到byte数组中
				in.read(buffer);
				result = EncodingUtils.getString(buffer, "UTF-8");
			} catch (Exception e) {
			}
		}
		return result;
	}

	public String getModuleUrl(Context context, CubeModule module) {
		String identifier = module.getIdentifier();
		// 模块是否本地模块
		if (module.getLocal() == null) {
			String path = Environment.getExternalStorageDirectory().getPath()
					+ "/" + URL.APP_PACKAGENAME;
			String url = path + "/www/" + identifier;
			// 检查文件是否存在

			if (CLFileUtil.isExistFile(url + "/" + "index.html")) {
				String moduleuUrl = "file:/" + url + "/index.html";
				return moduleuUrl;
			} else {
				Toast.makeText(context, "文件缺失，请重新下载", Toast.LENGTH_SHORT)
						.show();
				return null;
			}
		} else {
			String className = mPropertiesUtil.getString(
					module.getIdentifier(), "");
			return className;
		}
	}

	public void autoUpgrade(List<CubeModule> modules, Context context) {
		// AutoDownloadHelper.getInstance().setAutoDownloadCount(modules.size());
		for (CubeModule module : modules) {
			AutoDownloadHelper.getInstance().addDownloadTask(module);
		}
		for (CubeModule module : modules) {
			downLoadOrUpgradeModule(module, context);
		}
		Intent intent = new Intent();
		intent.setAction(BroadcastConstant.MODULE_AUTODOWNLOAD_START);
		context.sendBroadcast(intent);
	}

	public List<CubeModule> checkAutoDownload(String userName, Context context) {
		GsonBuilder builder = new GsonBuilder();
		Gson gson = builder.create();
		ArrayList<String> lists = new ArrayList<String>();
		String results = CLFileUtil.readFile(Environment
				.getExternalStorageDirectory().getPath()
				+ "/"
				+ URL.APP_PACKAGENAME
				+ "/"
				+ userName
				+ "_"
				+ "autoDownLoadFile.json");
		if (results != null) {
			lists = gson.fromJson(results, ArrayList.class);
			for (int i = 0; i < lists.size(); i++) {
				System.out.println("已下载过的==" + lists.get(i));
			}
		}

		List<CubeModule> unInstalledModules = new ArrayList<CubeModule>();
		List<CubeModule> isAutoShowModules = new ArrayList<CubeModule>();
		List<CubeModule> AutoShowModules = new ArrayList<CubeModule>();

		// 获得自动下载列表
		if (mCubeContentStatus.getInstalled_map().size() != 0) {
			for (List<CubeModule> list : mCubeContentStatus
					.getUninstalled_map().values()) {

				unInstalledModules.addAll(list);
			}
		}
		for (CubeModule module : unInstalledModules) {
			if (module.isAutoDownload()) {
				isAutoShowModules.add(module);
			}
		}
		for (int j = 0; j < isAutoShowModules.size(); j++) {
			Boolean isExit = false;
			for (int i = 0; i < lists.size(); i++) {
				if (isAutoShowModules.get(j).getIdentifier()
						.equals(lists.get(i))) {
					isExit = true;
					break;
				}
			}
			if (!isExit) {
				AutoShowModules.add(isAutoShowModules.get(j));
			}
		}

		return AutoShowModules;
	}

	public ArrayList<CubeModule> getAllAutoDownLoadModule() {
		ArrayList<CubeModule> unInstalledModules = new ArrayList<CubeModule>();
		ArrayList<CubeModule> isAutoShowModules = new ArrayList<CubeModule>();

		// 获得自动下载列表
		for (List<CubeModule> list : mCubeContentStatus.getUninstalled_map()
				.values()) {
			unInstalledModules.addAll(list);
		}
		for (CubeModule module : unInstalledModules) {
			if (module.isAutoDownload()) {
				isAutoShowModules.add(module);
			}
		}
		return isAutoShowModules;
	}

	public void autoDownload(List<CubeModule> modules, String userName,
			Context context) {

		// AutoDownloadHelper.getInstance().setAutoDownloadCount(total);
		for (CubeModule module : modules) {
			if (!AutoDownloadHelper.getInstance().addDownloadTask(module)) {
				// AutoDownloadHelper.getInstance().setAutoDownloadCount(total);
			}
		}
		for (CubeModule module : modules) {
			downLoadOrUpgradeModule(module, context);
		}

		saveAutoDownloadFile(modules, userName, context);
		Intent intent = new Intent();
		intent.setAction(BroadcastConstant.MODULE_AUTODOWNLOAD_START);
		context.sendBroadcast(intent);
	}

	public void cancelAutoDownload(List<CubeModule> modules, String userName,
			Context context) {
		saveAutoDownloadFile(modules, userName, context);
	}

	public void saveAutoDownloadFile(List<CubeModule> modules, String userName,
			Context contex) {
		ArrayList<String> list = new ArrayList<String>();
		for (CubeModule module : modules) {
			list.add(module.getIdentifier());
		}
		GsonBuilder builder = new GsonBuilder();
		Gson gson = builder.create();
		String json = gson.toJson(list);
		System.out.println(json);
		String filePath = Environment.getExternalStorageDirectory().getPath()
				+ "/" + URL.APP_PACKAGENAME + "/" + userName + "_"
				+ "autoDownLoadFile.json";
		File file = new File(filePath);
		if (file.exists()) {
			file.delete();
		}
		CLFileUtil.writeFile(filePath, json);
	}

	public void stopTask() {

	}

	public Intent showModule(Context context, CubeModule module) {
		String identifier = module.getIdentifier();

		// 模块是否本地模块
		Log.i("", "module.getLocal() ============== " + module.getLocal());
		if (module.getLocal() == null) {
			String path = Environment.getExternalStorageDirectory().getPath()
					+ "/" + URL.APP_PACKAGENAME;
			String url = path + "/www/" + identifier;
			// 检查文件是否存在
			if (CLFileUtil.isExistFile(url + "/index.html")) {

				Intent intent = new Intent();

				if ("com.foss.setting".equals(identifier)) {
					intent.setClass(context.getApplicationContext(),
							CubeSettingActivity.class);
				} else {
					intent.setClass(context.getApplicationContext(),
							CubeAndroid.class);
				}
				intent.putExtra("isPad", false);
				intent.putExtra("from", "main");
				intent.putExtra("path", Environment
						.getExternalStorageDirectory().getPath()
						+ "/"
						+ URL.APP_PACKAGENAME);
				intent.putExtra("identify", identifier);
				return intent;

			} else {
				Toast.makeText(context, "文件缺失，请重新下载", Toast.LENGTH_SHORT)
						.show();
				return null;
			}
		} else {
			// 模块为本地模块
			String className = mPropertiesUtil.getString(
					"phone_" + module.getIdentifier(), "");
			Log.i("", "module.getLocal() ============== className" + className);
			Intent i = new Intent();
			i.setClassName(context.getApplicationContext(), className);
			return i;
		}
	}

	/**
	 * [下载附件]<BR>
	 * [功能详细描述]
	 * 
	 * @param attach
	 *            2013-7-16 上午11:54:36
	 */
	public void downloadAttachMent(String attach) {

	}

	private void startWaitIngList() {
		if (mWaitIngLinkedMap.size() > 0) {
			CubeModule module = mWaitIngLinkedMap.entrySet().iterator().next()
					.getValue();
			mWaitIngLinkedMap.remove(module.getIdentifier());
			mWorkIngLinkedMap.put(module.getIdentifier(), module);
			if (isInstall(module)) {
				upgrade(module, ChameleonSDK.getCApplication().getContext());
			} else {
				install(module, ChameleonSDK.getCApplication().getContext());
			}
		}
	}

	/**
	 * 消除所有线程
	 */
	public void releaseTaskMananger() {
		if (mClTaskManager != null) {
			mClTaskManager.destory();
		}
	}

	public void destory() {
		// releaseTaskMananger();
		for (CLTask cl : mDownIngTaskMap.values()) {
			cl.cancel();
		}
		mDownIngTaskMap.clear();
		mWorkIngLinkedMap.clear();
		mWaitIngLinkedMap.clear();
	}

	public CubeContentStatus getmCubeContentStatus() {
		return mCubeContentStatus;
	}

	public void setmCubeContentStatus(CubeContentStatus mCubeContentStatus) {
		this.mCubeContentStatus = mCubeContentStatus;
	}

	public CubeContent getCubeContent() {
		return mCubeContent;
	}

	public void setCubeContent(CubeContent mCubeContent) {
		this.mCubeContent = mCubeContent;
	}

	private boolean isInstall(CubeModule m) {
		int type = m.getModuleType();
		if (m.getPrivileges() != null) {
			if (type == CubeModule.UPGRADABLE && type != CubeModule.UPGRADING
					&& type != CubeModule.DELETING) {
				return true;
			} else if (type == CubeModule.UNINSTALL
					&& type != CubeModule.INSTALLING
					&& type != CubeModule.DELETING) {
				return false;
			}
		}
		return false;
	}

}
